/*
 ************************************************************************************************
 *                                                                                              *
 *  OSA cooperative RTOS for Microchip PIC-controllers: PIC10/12/16/18/24/dsPIC                 *
 *                                                                                              *
 *  URL:        http://wiki.pic24.ru/doku.php/en/osa/ref/intro                                  *
 *              http://picosa.narod.ru                                                          *
 *                                                                                              *
 *----------------------------------------------------------------------------------------------*
 *                                                                                              *
 *  File:       osa_msg.h                                                                      *
 *                                                                                              *
 *  Compilers:  HT-PICC STD                                                                     *
 *              HT-PICC18 STD                                                                   *
 *              Microchip C18                                                                   *
 *              Microchip C30                                                                   *
 *                                                                                              *
 *  Programmer: Timofeev Victor                                                                 *
 *              osa@pic24.ru, testerplus@mail.ru                                                *
 *                                                                                              *
 *  Definition: Services to work with pointers to messages                                      *
 *                                                                                              *
 *                                                                                              *
 ************************************************************************************************
 */



/************************************************************************************************
 *                                                                                              *
 *                               P O I N T E R S   T O   M E S S A G E S                        *
 *                                                                                              *
 ************************************************************************************************/




// These macro used in services
#if defined(OS_ENABLE_INT_MSG)

    #define __OS_MSG_DI()       {_OS_temp = OS_DI();}
    #define __OS_MSG_RI()       {OS_RI(_OS_temp);}

#else

    #define __OS_MSG_DI()
    #define __OS_MSG_RI()

#endif


//------------------------------------------------------------------------------
// Check for message exists

#define OS_Msg_Check(msg_cb)          ((msg_cb).status & 1)
#define OS_Msg_Check2(msg_cb)          ((msg_cb).status)

//------------------------------------------------------------------------------
// Create message and zero it.

#define OS_Msg_Create(msg_cb)              \
    {                                       \
        __OS_MSG_DI();                      \
        (msg_cb).status = 0;                \
        (msg_cb).msg = (OST_MSG) 0;         \
        __OS_MSG_RI();                      \
    }

//------------------------------------------------------------------------------
// Make message free

#define OS_Msg_Clear(msg_cb)          (msg_cb).status = 0


//------------------------------------------------------------------------------
// Send message. If message is already exists then wait when it became free.

#define OS_Msg_Send(msg_cb, value)                                             \
    {                                                                           \
        if (OS_Msg_Check(msg_cb)) _OS_WAIT_EVENT(!OS_Msg_Check(msg_cb));      \
        __OS_MSG_DI();                                                          \
        (msg_cb).status = 1;                                                    \
        (msg_cb).msg = (OST_MSG) value;                                         \
        __OS_MSG_RI();                                                          \
    }

//------------------------------------------------------------------------------
// Send message. If message is already exists then it will be overwritten.

#define OS_Msg_Send_Now(msg_cb, value)                                         \
    {                                                                           \
        OS_Flags.bEventError = 0;                                               \
        if (OS_Msg_Check(msg_cb)) OS_Flags.bEventError = 1;                    \
        __OS_MSG_DI();                                                          \
        (msg_cb).status = 1;                                                    \
        (msg_cb).msg = (OST_MSG) value;                                         \
        __OS_MSG_RI();                                                          \
    }

//------------------------------------------------------------------------------
// Send message. If message is already exists then wait when it became free. Exit if timeout expired.

#define OS_Msg_Send_TO(msg_cb, value,timeout)                                  \
    {                                                                           \
        OS_Flags.bTimeout = 0;                                                  \
        if (OS_Msg_Check(msg_cb))                                              \
        {                                                                       \
            _OS_WAIT_EVENT_TIMEOUT(!OS_Msg_Check(msg_cb), timeout);            \
        }                                                                       \
        if (!OS_IsTimeout()){                                                   \
            __OS_MSG_DI();                                                      \
            (msg_cb).status = 1;                                                \
            (msg_cb).msg = (OST_MSG) value;                                     \
            __OS_MSG_RI();                                                      \
        }                                                                       \
    }

//------------------------------------------------------------------------------
// Wait for message. After waiting message is set free

#define OS_Msg_Wait(msg_cb, os_msg_type_var)                           \
    {                                                                   \
        _OS_WAIT_EVENT(OS_Msg_Check(msg_cb));                          \
        __OS_MSG_DI();                                                  \
        os_msg_type_var = (msg_cb).msg;                                 \
        OS_Msg_Clear(msg_cb);                                            \
        __OS_MSG_RI();                                                  \
    }


//------------------------------------------------------------------------------
// Wait for mesage. Exit if timeout expired.
#define OS_Msg_Wait_TO(msg_cb, os_msg_type_var,timeout)                \
    {                                                                   \
        os_msg_type_var = (OST_MSG) 0;                                  \
        _OS_WAIT_EVENT_TIMEOUT(OS_Msg_Check(msg_cb), timeout);         \
        if (!OS_IsTimeout()) {                                          \
            __OS_MSG_DI();                                              \
            os_msg_type_var = (msg_cb).msg;                             \
            OS_Msg_Clear(msg_cb);                                        \
            __OS_MSG_RI();                                              \
        }                                                               \
    }


//------------------------------------------------------------------------------
// Accept existing message. After accepting message is set free.
#define OS_Msg_Accept(msg_cb, os_msg_type_var)                         \
    {                                                                   \
        __OS_MSG_DI();                                                  \
        os_msg_type_var = (msg_cb).msg;                                 \
        OS_Msg_Clear(msg_cb);                                            \
        __OS_MSG_RI();                                                  \
    }




//------------------------------------------------------------------------------
#ifdef OS_ENABLE_INT_MSG
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Send message from interrupt. If message is already exists then it will be overwritten.
#define OS_Msg_Send_I(msg_cb, value)                                   \
    {                                                                   \
        OS_Flags.bEventError = 0;                                       \
        if (OS_Msg_Check(msg_cb)) OS_Flags.bEventError = 1;            \
        (msg_cb).status = 1;                                            \
        (msg_cb).msg = (OST_MSG) value;                                 \
    }

//------------------------------------------------------------------------------
// Accept existing message. After accepting message is set free.
#define OS_IntAcceptMsg(msg_cb, os_msg_type_var)                        \
    {                                                                   \
        os_msg_type_var = (msg_cb).msg;                                 \
        OS_Msg_Clear(msg_cb);                                            \
    }


//------------------------------------------------------------------------------
#endif  // OS_ENABLE_INT_SERVICE
//------------------------------------------------------------------------------
















